package com.genexususa.eo.google.connection;

import com.genexususa.eo.google.data.*;
import com.google.api.ads.adwords.axis.v201409.cm.*;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;


public class AdGroupManager {


    private static final int PAGE_SIZE = 5000;
    private String _clientId;

    public void SetClientId(String clientId) {
        this._clientId = clientId;
    }

    public String GetClientId() {
        return _clientId;
    }

    public void Finalize() {

        SessionController sc = SessionController.getInstance();
        sc.RemoveSession(_clientId);
    }


    public String CreateAdGroup(String xml) {

        try {

            String result = "";

            // Get the instance of service's factory
            ServiceFactory sf = ServiceFactory.getInstance();

            // Get AdGroup Service
            AdGroupServiceInterface adGroupService = sf.GetAdGroupService(this.GetClientId());

            //GA_ResultCreateAdgroup res = new GA_ResultCreateAdgroup();

            GA_Result res = new GA_Result();


            Document doc = loadXMLFromString(xml);

            XPathFactory factory = XPathFactory.newInstance();
            XPath xpath = factory.newXPath();

            XPathExpression expr
                    = xpath.compile("//GA_AdGroup");

            Object adGroupNodes = expr.evaluate(doc, XPathConstants.NODESET);

            NodeList adGroups = (NodeList) adGroupNodes;

            ArrayList<AdGroup> createdAdGroups = new ArrayList<AdGroup>();

            HashMap<String, Long> gxIds = new HashMap<String, Long>();

            HashMap<String, Long> campaignGxIds = new HashMap<String, Long>();

            if (adGroups.getLength() > 0) {

                for (int i = 0; i < adGroups.getLength(); i++) { // For all GA_AdGroup Node

                    Node n = adGroups.item(i);

                    NodeList children = n.getChildNodes();

                    AdGroup adGroup = new AdGroup();

                    String adGroupName = "";

                    Long gxId = 0L;

                    Long campaignGxId = 0L;

                    for (int j = 0; j < children.getLength(); j++) { // Children of each GA_AdGroup Node

                        if (children.item(j).getNodeName().equalsIgnoreCase("CampaignId")) {
                            adGroup.setCampaignId(Long.parseLong(children.item(j).getTextContent()));
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("Name")) {
                            adGroup.setName(children.item(j).getTextContent());
                            adGroupName = children.item(j).getTextContent();
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("AdGroupGxId")) {
                            gxId = Long.parseLong(children.item(j).getTextContent());
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("SubCampaignGxId")) {
                            campaignGxId = Long.parseLong(children.item(j).getTextContent());
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("Status")) {

                            if (children.item(j).getTextContent().equalsIgnoreCase("E")) {
                                adGroup.setStatus(AdGroupStatus.ENABLED);
                            } else if (children.item(j).getTextContent().equalsIgnoreCase("P")) {
                                adGroup.setStatus(AdGroupStatus.PAUSED);
                            } else if (children.item(j).getTextContent().equalsIgnoreCase("D")) {
                                adGroup.setStatus(AdGroupStatus.REMOVED);
                            }
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("Settings")) {
                            adGroup.setSettings(GetSettings(children.item(j).getChildNodes()));
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("BiddingStrategyConfiguration")) {

                            BiddingStrategyConfiguration bsc = new BiddingStrategyConfiguration();
                            NodeList biddingStrategyConfiguration = children.item(j).getChildNodes();

                            if (biddingStrategyConfiguration.getLength() > 0) {
                                for (int a=0; a<biddingStrategyConfiguration.getLength(); a++) {
                                    if (biddingStrategyConfiguration.item(a).getNodeName().equalsIgnoreCase("BiddingScheme")) {

                                        NodeList strategies = biddingStrategyConfiguration.item(a).getChildNodes();

                                        if (strategies.getLength() > 0) {

                                            for (int y = 0; y < strategies.getLength(); y++) {

                                                if (strategies.item(y).getNodeName().equalsIgnoreCase("BSConversionOptimizer")) {
                                                    Node bsConversionOptimizer = strategies.item(y);

                                                    NodeList bsConversionOptimizerChildren = bsConversionOptimizer.getChildNodes();

                                                    if (bsConversionOptimizerChildren.getLength() > 0) {

                                                        ConversionOptimizerBiddingScheme co = new ConversionOptimizerBiddingScheme();

                                                        for (int index = 0; index < bsConversionOptimizerChildren.getLength(); index++) {

                                                            if (bsConversionOptimizerChildren.item(index).getNodeName().equalsIgnoreCase("BSConvOptPricingModel")) {
                                                                if (bsConversionOptimizerChildren.item(index).getTextContent().equalsIgnoreCase("C")) {
                                                                    co.setPricingMode(ConversionOptimizerBiddingSchemePricingMode.CLICKS);
                                                                } else if (bsConversionOptimizerChildren.item(index).getTextContent().equalsIgnoreCase("CN")) {
                                                                    co.setPricingMode(ConversionOptimizerBiddingSchemePricingMode.CONVERSIONS);
                                                                }
                                                            }

                                                            if (bsConversionOptimizerChildren.item(index).getNodeName().equalsIgnoreCase("BSConvOptBidType")) {
                                                                if (bsConversionOptimizerChildren.item(index).getTextContent().equalsIgnoreCase("T")) {
                                                                    co.setBidType(ConversionOptimizerBiddingSchemeBidType.TARGET_CPA);
                                                                } /*else if (bsConversionOptimizerChildren.item(index).getTextContent().equalsIgnoreCase("M")) {
                                                                    co.setBidType(ConversionOptimizerBiddingSchemeBidType.MAX_CPA);
                                                                }*/
                                                            }
                                                        }
                                                        bsc.setBiddingScheme(co);
                                                    }

                                                }

                                                if (strategies.item(y).getNodeName().equalsIgnoreCase("BSManualCPC")) {

                                                    Node manualCPCNode = strategies.item(y);

                                                    NodeList manualCPCChildren = manualCPCNode.getChildNodes();

                                                    ManualCpcBiddingScheme manualCPC = new ManualCpcBiddingScheme();

                                                    for (int index = 0; index < manualCPCChildren.getLength(); index++) {

                                                        if (manualCPCChildren.item(index).getNodeName().equalsIgnoreCase("enhancedCpcEnabled")) {
                                                            if (manualCPCChildren.item(index).getTextContent().equalsIgnoreCase("true")) {
                                                                manualCPC.setEnhancedCpcEnabled(true);
                                                            } else {
                                                                manualCPC.setEnhancedCpcEnabled(false);
                                                            }
                                                        }
                                                    }

                                                    bsc.setBiddingScheme(manualCPC);
                                                }

                                                if (strategies.item(y).getNodeName().equalsIgnoreCase("BSManualCPM")) {
                                                    Node manualCPMNode = strategies.item(y);

                                                    NodeList manualCPMChildren = manualCPMNode.getChildNodes();

                                                    for (int index = 0; index < manualCPMChildren.getLength(); index++) {

                                                        if (manualCPMChildren.item(index).getNodeName().equalsIgnoreCase("enable")) {
                                                            if (manualCPMChildren.item(index).getTextContent().equalsIgnoreCase("true")) {
                                                                bsc.setBiddingScheme(new ManualCpmBiddingScheme());
                                                            }
                                                        }
                                                    }
                                                }

                                                /*if (strategies.item(y).getNodeName().equalsIgnoreCase("BSPercentCPA")) {
                                                    Node bsPercentCPANode = strategies.item(y);

                                                    NodeList bsPercentCPANodeChildren = bsPercentCPANode.getChildNodes();

                                                    for (int index = 0; index < bsPercentCPANodeChildren.getLength(); index++) {

                                                        if (bsPercentCPANodeChildren.item(index).getNodeName().equalsIgnoreCase("enable")) {
                                                            if (bsPercentCPANodeChildren.item(index).getTextContent().equalsIgnoreCase("true")) {
                                                                bsc.setBiddingScheme(new PercentCpaBiddingScheme());
                                                            }
                                                        }
                                                    }
                                                }   */

                                                if (strategies.item(y).getNodeName().equalsIgnoreCase("BSBudgetOptimizer")) {

                                                    Node bsBudgetOptimizerNode = strategies.item(y);

                                                    NodeList bsBudgetOptimizerNodeChildren = bsBudgetOptimizerNode.getChildNodes();

                                                    BudgetOptimizerBiddingScheme bo = new BudgetOptimizerBiddingScheme();

                                                    for (int index = 0; index < bsBudgetOptimizerNodeChildren.getLength(); index++) {

                                                        if (bsBudgetOptimizerNodeChildren.item(index).getNodeName().equalsIgnoreCase("enhancedCpcEnabled")) {

                                                            if (bsBudgetOptimizerNodeChildren.item(index).getTextContent().equalsIgnoreCase("true")) {
                                                                bo.setEnhancedCpcEnabled(true);
                                                            } else {
                                                                bo.setEnhancedCpcEnabled(false);
                                                            }
                                                        }

                                                        if (bsBudgetOptimizerNodeChildren.item(index).getNodeName().equalsIgnoreCase("bidCeiling")) {

                                                            Money bidCeilingMoney = new Money();

                                                            Double amount = Double.parseDouble(bsBudgetOptimizerNodeChildren.item(index).getTextContent());

                                                            Long microAmount = (long) (amount * 10000000L / 10);
                                                            bidCeilingMoney.setMicroAmount(microAmount);

                                                            bo.setBidCeiling(bidCeilingMoney);
                                                        }
                                                    }

                                                    bsc.setBiddingScheme(bo);

                                                }
                                            }
                                        }
                                    }
                                    if (biddingStrategyConfiguration.item(a).getNodeName().equalsIgnoreCase("Bids")) {
                                        Bids bids = GetBids(biddingStrategyConfiguration.item(a).getChildNodes());
                                        if (bids != null) {
                                            Bids[] bidsCollection = { bids };
                                            bsc.setBids(bidsCollection);
                                        }
                                    }
                                }
                            }
                            adGroup.setBiddingStrategyConfiguration(bsc);
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("ExperimentData")) {
                            adGroup.setExperimentData(GetExperimentData(children.item(j).getChildNodes()));
                        }

                        /*if (children.item(j).getNodeName().equalsIgnoreCase("Statistics")) {
                            adGroup.setStats(GetStats(children.item(j).getChildNodes()));
                        } */

                    }

                    gxIds.put(adGroupName, gxId);
                    campaignGxIds.put(adGroupName, campaignGxId);
                    createdAdGroups.add(adGroup);

                }

            }


            ArrayList<GA_ResultItem> created = new ArrayList<GA_ResultItem>();

            ArrayList<AdGroupOperation> ops = new ArrayList<AdGroupOperation>();

            for (AdGroup adGroup : createdAdGroups) {


                AdGroupOperation operation = new AdGroupOperation();
                operation.setOperand(adGroup);
                operation.setOperator(Operator.ADD);


                ops.add(operation);

            }

            AdGroupOperation[] opsArray = new AdGroupOperation[]{};

            AdGroupOperation[] operations = ops.toArray(opsArray);


            AdGroupReturnValue resultValue = adGroupService.mutate(operations);

            Thread.sleep(1000);

            int j = 0;

            for (int i = 0; i < resultValue.getValue().length; i++) {

                GA_ResultItem createAdGroup = new GA_ResultItem();


                createAdGroup.AdGroupName = createdAdGroups.get(i).getName();
                createAdGroup.CampaignId = createdAdGroups.get(i).getCampaignId();
                createAdGroup.SubCampName = createdAdGroups.get(i).getCampaignName();
                createAdGroup.AdGroupGxId = gxIds.get(createdAdGroups.get(i).getName());
                createAdGroup.SubCampaignGxId = campaignGxIds.get(createdAdGroups.get(i).getName());
                createAdGroup.HasError = false;


                if (resultValue.getValue(i).getId() == null || resultValue.getValue(i).getId() == 0L) {

                    createAdGroup.AdGroupId = 0L;
                    createAdGroup.HasError = true;

                    ErrorsStruct errors = new ErrorsStruct();

                    errors.Message = resultValue.getPartialFailureErrors(j).getErrorString();

                    errors.Errors = new ArrayList<com.genexususa.eo.google.data.Error>();

                    com.genexususa.eo.google.data.Error err = new com.genexususa.eo.google.data.Error();

                    err.ErrorString = resultValue.getPartialFailureErrors(j).getErrorString();
                    err.fieldPath = resultValue.getPartialFailureErrors(j).getFieldPath();
                    err.Trigger = resultValue.getPartialFailureErrors(j).getTrigger();
                    err.Type = resultValue.getPartialFailureErrors(j).getApiErrorType();

                    j++;

                    errors.Errors.add(err);

                    createAdGroup.Errors = errors;

                    created.add(createAdGroup);

                } else {

                    createAdGroup.AdGroupId = resultValue.getValue(i).getId();

                    created.add(createAdGroup);
                }

            }


            try {

                JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class);

                Marshaller marshallerObj = contextObj.createMarshaller();
                marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                StringWriter sw = new StringWriter();

                res.Items = created;

                marshallerObj.marshal(res, sw);
                result = sw.getBuffer().toString();
                System.out.println(result);
                String s = "";

            } catch (Exception exc) {

            }

            return result;

        } catch (Exception exc) {

            GA_Result res = new GA_Result();

            ArrayList<GA_ResultItem> items = new ArrayList<GA_ResultItem>();

            GA_ResultItem error = new GA_ResultItem();

            ErrorsStruct errors = new ErrorsStruct();

            errors.Message = exc.getMessage();

            errors.Errors = new ArrayList<com.genexususa.eo.google.data.Error>();

            com.genexususa.eo.google.data.Error err = new com.genexususa.eo.google.data.Error();

            StringWriter st = new StringWriter();
            exc.printStackTrace(new PrintWriter(st));

            err.UnknownError = st.toString();

            errors.Errors.add(err);

            error.Errors = errors;

            error.HasError = true;

            items.add(error);

            String result = "";

            try {

                JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class);

                Marshaller marshallerObj = contextObj.createMarshaller();
                marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                StringWriter sw = new StringWriter();

                res.Items = items;

                marshallerObj.marshal(res, sw);
                result = sw.getBuffer().toString();
                System.out.println(result);
                return result;

            } catch (Exception ex) {
                ex.printStackTrace();
                result = ex.getMessage();
                return result;
            }
        }
    }

    public String UpdateAdGroup(String xml) {

        try {

            String result = "";

            // Get the instance of service's factory
            ServiceFactory sf = ServiceFactory.getInstance();

            // Get AdGroup Service
            AdGroupServiceInterface adGroupService = sf.GetAdGroupService(this.GetClientId());

            //GA_ResultCreateAdgroup res = new GA_ResultCreateAdgroup();

            GA_Result res = new GA_Result();


            Document doc = loadXMLFromString(xml);

            XPathFactory factory = XPathFactory.newInstance();
            XPath xpath = factory.newXPath();

            XPathExpression expr
                    = xpath.compile("//GA_AdGroup");

            Object adGroupNodes = expr.evaluate(doc, XPathConstants.NODESET);

            NodeList adGroups = (NodeList) adGroupNodes;

            ArrayList<AdGroup> createdAdGroups = new ArrayList<AdGroup>();

            HashMap<String, Long> gxIds = new HashMap<String, Long>();

            HashMap<String, Long> campaignGxIds = new HashMap<String, Long>();

            if (adGroups.getLength() > 0) {

                for (int i = 0; i < adGroups.getLength(); i++) { // For all GA_AdGroup Node

                    Node n = adGroups.item(i);

                    NodeList children = n.getChildNodes();

                    AdGroup adGroup = new AdGroup();

                    String adGroupName = "";

                    Long gxId = 0L;

                    Long campaignGxId = 0L;

                    for (int j = 0; j < children.getLength(); j++) { // Children of each GA_AdGroup Node

                        if (children.item(j).getNodeName().equalsIgnoreCase("CampaignId")) {
                            adGroup.setCampaignId(Long.parseLong(children.item(j).getTextContent()));
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("Id")) {
                            adGroup.setId(Long.parseLong(children.item(j).getTextContent()));
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("Name")) {
                            adGroup.setName(children.item(j).getTextContent());
                            adGroupName = children.item(j).getTextContent();
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("AdGroupGxId")) {
                            gxId = Long.parseLong(children.item(j).getTextContent());
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("SubCampaignGxId")) {
                            campaignGxId = Long.parseLong(children.item(j).getTextContent());
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("Status")) {

                            if (children.item(j).getTextContent().equalsIgnoreCase("E")) {
                                adGroup.setStatus(AdGroupStatus.ENABLED);
                            } else if (children.item(j).getTextContent().equalsIgnoreCase("P")) {
                                adGroup.setStatus(AdGroupStatus.PAUSED);
                            } else if (children.item(j).getTextContent().equalsIgnoreCase("D")) {
                                adGroup.setStatus(AdGroupStatus.REMOVED);
                            }
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("Settings")) {
                            adGroup.setSettings(GetSettings(children.item(j).getChildNodes()));
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("BiddingStrategyConfiguration")) {

                            NodeList biddingStrategyConfiguration = children.item(j).getChildNodes();

                            if (biddingStrategyConfiguration.getLength() > 0) {
                                for (int a=0; a<biddingStrategyConfiguration.getLength(); a++) {
                                    BiddingStrategyConfiguration bsc = new BiddingStrategyConfiguration();

                                    if (biddingStrategyConfiguration.item(a).getNodeName().equalsIgnoreCase("BiddingScheme")) {

                                        NodeList strategies = biddingStrategyConfiguration.item(a).getChildNodes();

                                        if (strategies.getLength() > 0) {

                                            for (int y = 0; y < strategies.getLength(); y++) {

                                                if (strategies.item(y).getNodeName().equalsIgnoreCase("BSConversionOptimizer")) {
                                                    Node bsConversionOptimizer = strategies.item(y);

                                                    NodeList bsConversionOptimizerChildren = bsConversionOptimizer.getChildNodes();

                                                    if (bsConversionOptimizerChildren.getLength() > 0) {

                                                        ConversionOptimizerBiddingScheme co = new ConversionOptimizerBiddingScheme();

                                                        for (int index = 0; index < bsConversionOptimizerChildren.getLength(); index++) {

                                                            if (bsConversionOptimizerChildren.item(index).getNodeName().equalsIgnoreCase("BSConvOptPricingModel")) {
                                                                if (bsConversionOptimizerChildren.item(index).getTextContent().equalsIgnoreCase("C")) {
                                                                    co.setPricingMode(ConversionOptimizerBiddingSchemePricingMode.CLICKS);
                                                                } else if (bsConversionOptimizerChildren.item(index).getTextContent().equalsIgnoreCase("CN")) {
                                                                    co.setPricingMode(ConversionOptimizerBiddingSchemePricingMode.CONVERSIONS);
                                                                }
                                                            }

                                                            if (bsConversionOptimizerChildren.item(index).getNodeName().equalsIgnoreCase("BSConvOptBidType")) {
                                                                if (bsConversionOptimizerChildren.item(index).getTextContent().equalsIgnoreCase("T")) {
                                                                    co.setBidType(ConversionOptimizerBiddingSchemeBidType.TARGET_CPA);
                                                                }/* else if (bsConversionOptimizerChildren.item(index).getTextContent().equalsIgnoreCase("M")) {
                                                                    co.setBidType(ConversionOptimizerBiddingSchemeBidType.MAX_CPA);
                                                                }      */
                                                            }
                                                        }
                                                        bsc.setBiddingScheme(co);
                                                    }

                                                }

                                                if (strategies.item(y).getNodeName().equalsIgnoreCase("BSManualCPC")) {

                                                    Node manualCPCNode = strategies.item(y);

                                                    NodeList manualCPCChildren = manualCPCNode.getChildNodes();

                                                    ManualCpcBiddingScheme manualCPC = new ManualCpcBiddingScheme();

                                                    for (int index = 0; index < manualCPCChildren.getLength(); index++) {

                                                        if (manualCPCChildren.item(index).getNodeName().equalsIgnoreCase("enhancedCpcEnabled")) {
                                                            if (manualCPCChildren.item(index).getTextContent().equalsIgnoreCase("true")) {
                                                                manualCPC.setEnhancedCpcEnabled(true);
                                                            } else {
                                                                manualCPC.setEnhancedCpcEnabled(false);
                                                            }
                                                        }
                                                    }

                                                    bsc.setBiddingScheme(manualCPC);
                                                }

                                                if (strategies.item(y).getNodeName().equalsIgnoreCase("BSManualCPM")) {
                                                    Node manualCPMNode = strategies.item(y);

                                                    NodeList manualCPMChildren = manualCPMNode.getChildNodes();

                                                    for (int index = 0; index < manualCPMChildren.getLength(); index++) {

                                                        if (manualCPMChildren.item(index).getNodeName().equalsIgnoreCase("enable")) {
                                                            if (manualCPMChildren.item(index).getTextContent().equalsIgnoreCase("true")) {
                                                                bsc.setBiddingScheme(new ManualCpmBiddingScheme());
                                                            }
                                                        }
                                                    }
                                                }

                                                /*if (strategies.item(y).getNodeName().equalsIgnoreCase("BSPercentCPA")) {
                                                    Node bsPercentCPANode = strategies.item(y);

                                                    NodeList bsPercentCPANodeChildren = bsPercentCPANode.getChildNodes();

                                                    for (int index = 0; index < bsPercentCPANodeChildren.getLength(); index++) {

                                                        if (bsPercentCPANodeChildren.item(index).getNodeName().equalsIgnoreCase("enable")) {
                                                            if (bsPercentCPANodeChildren.item(index).getTextContent().equalsIgnoreCase("true")) {
                                                                bsc.setBiddingScheme(new PercentCpaBiddingScheme());
                                                            }
                                                        }
                                                    }
                                                }  */

                                                if (strategies.item(y).getNodeName().equalsIgnoreCase("BSBudgetOptimizer")) {

                                                    Node bsBudgetOptimizerNode = strategies.item(y);

                                                    NodeList bsBudgetOptimizerNodeChildren = bsBudgetOptimizerNode.getChildNodes();

                                                    BudgetOptimizerBiddingScheme bo = new BudgetOptimizerBiddingScheme();

                                                    for (int index = 0; index < bsBudgetOptimizerNodeChildren.getLength(); index++) {

                                                        if (bsBudgetOptimizerNodeChildren.item(index).getNodeName().equalsIgnoreCase("enhancedCpcEnabled")) {

                                                            if (bsBudgetOptimizerNodeChildren.item(index).getTextContent().equalsIgnoreCase("true")) {
                                                                bo.setEnhancedCpcEnabled(true);
                                                            } else {
                                                                bo.setEnhancedCpcEnabled(false);
                                                            }
                                                        }

                                                        if (bsBudgetOptimizerNodeChildren.item(index).getNodeName().equalsIgnoreCase("bidCeiling")) {

                                                            Money bidCeilingMoney = new Money();

                                                            Double amount = Double.parseDouble(bsBudgetOptimizerNodeChildren.item(index).getTextContent());

                                                            Long microAmount = (long) (amount * 10000000L / 10);
                                                            bidCeilingMoney.setMicroAmount(microAmount);

                                                            bo.setBidCeiling(bidCeilingMoney);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    //if (children.item(j).getNodeName().equalsIgnoreCase("Bids")) {
                                    if(biddingStrategyConfiguration.item(a).getNodeName().equalsIgnoreCase("Bids")){
                                        //Bids bids = GetBids(children.item(j).getChildNodes());
                                        Bids bids = GetBids(biddingStrategyConfiguration.item(a).getChildNodes());
                                        if (bids != null) {
                                            Bids[] bidsCollection = { bids };
                                            bsc.setBids(bidsCollection);
                                        }
                                    }

                                    adGroup.setBiddingStrategyConfiguration(bsc);
                                }
                            }
                        }

                        if (children.item(j).getNodeName().equalsIgnoreCase("ExperimentData")) {
                            adGroup.setExperimentData(GetExperimentData(children.item(j).getChildNodes()));
                        }

                        /*if (children.item(j).getNodeName().equalsIgnoreCase("Statistics")) {
                            adGroup.setStats(GetStats(children.item(j).getChildNodes()));
                        } */

                    }

                    gxIds.put(adGroupName, gxId);
                    campaignGxIds.put(adGroupName, campaignGxId);

                    createdAdGroups.add(adGroup);

                }

            }


            ArrayList<GA_ResultItem> created = new ArrayList<GA_ResultItem>();

            ArrayList<AdGroupOperation> ops = new ArrayList<AdGroupOperation>();

            for (AdGroup adGroup : createdAdGroups) {


                AdGroupOperation operation = new AdGroupOperation();
                operation.setOperand(adGroup);
                operation.setOperator(Operator.SET);


                ops.add(operation);
            }

            AdGroupOperation[] opsArray = new AdGroupOperation[]{};

            AdGroupOperation[] operations = ops.toArray(opsArray);

            AdGroupReturnValue resultValue = adGroupService.mutate(operations);

            Thread.sleep(1000);

            int j = 0;

            for (int i = 0; i < resultValue.getValue().length; i++) {

                GA_ResultItem createAdGroup = new GA_ResultItem();


                createAdGroup.AdGroupName = createdAdGroups.get(i).getName();
                createAdGroup.CampaignId = createdAdGroups.get(i).getCampaignId();
                createAdGroup.SubCampName = createdAdGroups.get(i).getCampaignName();
                createAdGroup.AdGroupGxId = gxIds.get(createdAdGroups.get(i).getName());
                createAdGroup.SubCampaignGxId = campaignGxIds.get(createdAdGroups.get(i).getName());
                createAdGroup.HasError = false;


                if (resultValue.getValue(i).getId() == null || resultValue.getValue(i).getId() == 0L) {

                    createAdGroup.AdGroupId = 0L;
                    createAdGroup.HasError = true;

                    ErrorsStruct errors = new ErrorsStruct();

                    errors.Message = resultValue.getPartialFailureErrors(j).getErrorString();

                    errors.Errors = new ArrayList<com.genexususa.eo.google.data.Error>();

                    com.genexususa.eo.google.data.Error err = new com.genexususa.eo.google.data.Error();

                    err.ErrorString = resultValue.getPartialFailureErrors(j).getErrorString();
                    err.fieldPath = resultValue.getPartialFailureErrors(j).getFieldPath();
                    err.Trigger = resultValue.getPartialFailureErrors(j).getTrigger();
                    err.Type = resultValue.getPartialFailureErrors(j).getApiErrorType();

                    j++;

                    errors.Errors.add(err);

                    createAdGroup.Errors = errors;

                    created.add(createAdGroup);

                } else {

                    createAdGroup.AdGroupId = resultValue.getValue(i).getId();

                    created.add(createAdGroup);
                }

            }


            try {

                JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class);

                Marshaller marshallerObj = contextObj.createMarshaller();
                marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                StringWriter sw = new StringWriter();

                res.Items = created;

                marshallerObj.marshal(res, sw);
                result = sw.getBuffer().toString();
                System.out.println(result);
                String s = "";

            } catch (Exception exc) {

            }


            return result;

        } catch (Exception exc) {

            GA_Result res = new GA_Result();

            ArrayList<GA_ResultItem> items = new ArrayList<GA_ResultItem>();

            GA_ResultItem error = new GA_ResultItem();

            ErrorsStruct errors = new ErrorsStruct();

            errors.Message = exc.getMessage();

            errors.Errors = new ArrayList<com.genexususa.eo.google.data.Error>();

            com.genexususa.eo.google.data.Error err = new com.genexususa.eo.google.data.Error();

            StringWriter st = new StringWriter();
            exc.printStackTrace(new PrintWriter(st));

            err.UnknownError = st.toString();

            errors.Errors.add(err);

            error.Errors = errors;

            error.HasError = true;

            items.add(error);

            String result = "";

            try {

                JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class);

                Marshaller marshallerObj = contextObj.createMarshaller();
                marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                StringWriter sw = new StringWriter();

                res.Items = items;

                marshallerObj.marshal(res, sw);
                result = sw.getBuffer().toString();
                System.out.println(result);
                return result;

            } catch (Exception ex) {
                ex.printStackTrace();
                result = ex.getMessage();
                return result;
            }
        }

    }

    private Bids GetBids(NodeList children) {

        for (int i = 0; i < children.getLength(); i++) {

           /* if (children.item(i).getNodeName().equalsIgnoreCase("PercentCPA")) {

                PercentCpaBid pCpaBids = new PercentCpaBid();

                for (int j = 0; j < children.item(i).getChildNodes().getLength(); j++) {

                    if (children.item(i).getChildNodes().item(j).getNodeName().equalsIgnoreCase("PercentCpa")) {
                        pCpaBids.setBid(Integer.parseInt(children.item(i).getChildNodes().item(j).getTextContent()));
                    }
                }

                return pCpaBids;
            }                       */



            if (children.item(i).getNodeName().equalsIgnoreCase("ConversionOptimizer")) {

                CpaBid cOptimizerBids = new CpaBid();

                for (int j = 0; j < children.item(i).getChildNodes().getLength(); j++) {

                    if (children.item(i).getChildNodes().item(j).getNodeName().equalsIgnoreCase("TargetCpa")) {

                        Money targetCpaMoney = new Money();

                        Double amount = Double.parseDouble(children.item(i).getChildNodes().item(j).getTextContent());

                        Long microAmount = (long) (amount * 10000000L / 10);

                        targetCpaMoney.setMicroAmount(microAmount);

                        cOptimizerBids.setBid(targetCpaMoney);

                        return cOptimizerBids;
                    }

                }
            }

            if (children.item(i).getNodeName().equalsIgnoreCase("ManualCPC")) {

                CpcBid manualCPC = new CpcBid();

                for (int j = 0; j < children.item(i).getChildNodes().getLength(); j++) {

                    if (children.item(i).getChildNodes().item(j).getNodeName().equalsIgnoreCase("KeywordMaxCpc")) {

                        Money keywordMaxMoney = new Money();

                        Double amount = Double.parseDouble(children.item(i).getChildNodes().item(j).getTextContent());

                        Long microAmount = (long) (amount * 10000000L / 10);

                        keywordMaxMoney.setMicroAmount(microAmount);

                        manualCPC.setBid(keywordMaxMoney);

                    }

                    if (children.item(i).getChildNodes().item(j).getNodeName().equalsIgnoreCase("KeywordContentMaxCpc")) {

                        Money keywordContentMaxMoney = new Money();

                        Double amount = Double.parseDouble(children.item(i).getChildNodes().item(j).getTextContent());

                        Long microAmount = (long) (amount * 10000000L / 10);

                        keywordContentMaxMoney.setMicroAmount(microAmount);

                        manualCPC.setBid(keywordContentMaxMoney);
                    }

                }

                return manualCPC;

            }

            if (children.item(i).getNodeName().equalsIgnoreCase("ManualCPM")) {

                CpmBid manualCPM = new CpmBid();

                for (int j = 0; j < children.item(i).getChildNodes().getLength(); j++) {

                    if (children.item(i).getChildNodes().item(j).getNodeName().equalsIgnoreCase("MaxCpm")) {

                        Money maxCPMMoney = new Money();

                        Double amount = Double.parseDouble(children.item(i).getChildNodes().item(j).getTextContent());

                        Long microAmount = (long) (amount * 10000000L / 10);

                        maxCPMMoney.setMicroAmount(microAmount);

                        manualCPM.setBid(maxCPMMoney);
                    }

                }

                return manualCPM;

            }


        }


        return null;  //To change body of created methods use File | Settings | File Templates.
    }

    private Setting[] GetSettings(NodeList children) {

        ArrayList<Setting> settings = new ArrayList<Setting>();

        for (int i = 0; i < children.getLength(); i++) {

            if (children.item(i).getNodeName().equalsIgnoreCase("TargettingSetting")) {

                TargetingSetting ts = new TargetingSetting();

                ArrayList<TargetingSettingDetail> tsDetails = new ArrayList<TargetingSettingDetail>();
                for (int j = 0; j < children.item(i).getChildNodes().getLength(); j++) {

                    TargetingSettingDetail tsd = new TargetingSettingDetail();

                    if (children.item(i).getChildNodes().item(j).getNodeName().equalsIgnoreCase("CriterionTypeGroup")) {

                        if (children.item(i).getChildNodes().item(j).getTextContent().equalsIgnoreCase("U")) {
                            tsd.setCriterionTypeGroup(CriterionTypeGroup.USER_INTEREST_AND_LIST);
                        } else if (children.item(i).getChildNodes().item(j).getTextContent().equalsIgnoreCase("V")) {
                            tsd.setCriterionTypeGroup(CriterionTypeGroup.VERTICAL);
                        } else if (children.item(i).getChildNodes().item(j).getTextContent().equalsIgnoreCase("G")) {
                            tsd.setCriterionTypeGroup(CriterionTypeGroup.GENDER);
                        } else if (children.item(i).getChildNodes().item(j).getTextContent().equalsIgnoreCase("A")) {
                            tsd.setCriterionTypeGroup(CriterionTypeGroup.AGE_RANGE);
                        } else if (children.item(i).getChildNodes().item(j).getTextContent().equalsIgnoreCase("P")) {
                            tsd.setCriterionTypeGroup(CriterionTypeGroup.PLACEMENT);
                        } else if (children.item(i).getChildNodes().item(j).getTextContent().equalsIgnoreCase("UN")) {
                            tsd.setCriterionTypeGroup(CriterionTypeGroup.UNKNOWN);
                        } else if (children.item(i).getChildNodes().item(j).getTextContent().equalsIgnoreCase("K")) {
                            tsd.setCriterionTypeGroup(CriterionTypeGroup.KEYWORD);
                        }

                        tsDetails.add(tsd);
                    }

                    if (children.item(i).getChildNodes().item(j).getNodeName().equalsIgnoreCase("TargetAll")) {
                        tsd.setTargetAll(Boolean.parseBoolean(children.item(i).getChildNodes().item(j).getTextContent()));
                        tsDetails.add(tsd);
                    }
                }

                TargetingSettingDetail[] detailsArray = new TargetingSettingDetail[]{};
                ts.setDetails(tsDetails.toArray(detailsArray));

                settings.add(ts);
            }
        }

        Setting[] result = new Setting[]{};

        settings.toArray(result);

        return result;
    }

    private AdGroupExperimentData GetExperimentData(NodeList children) {
        AdGroupExperimentData adGroupExperimentData = new AdGroupExperimentData();
        for (int i = 0; i < children.getLength(); i++) {
            if (children.item(i).getNodeName().equalsIgnoreCase("Id")) {
                adGroupExperimentData.setExperimentId(Long.valueOf(children.item(i).getTextContent()));
            }
            if (children.item(i).getNodeName().equalsIgnoreCase("DeltaStatus")) {
                if (children.item(i).getTextContent().equalsIgnoreCase("E")) {
                    adGroupExperimentData.setExperimentDeltaStatus(ExperimentDeltaStatus.EXPERIMENT_ONLY);
                } else if (children.item(i).getTextContent().equalsIgnoreCase("M")) {
                    adGroupExperimentData.setExperimentDeltaStatus(ExperimentDeltaStatus.MODIFIED);
                } else if (children.item(i).getTextContent().equalsIgnoreCase("C")) {
                    adGroupExperimentData.setExperimentDeltaStatus(ExperimentDeltaStatus.CONTROL_ONLY);
                } else {
                    adGroupExperimentData.setExperimentDeltaStatus(ExperimentDeltaStatus.UNKNOWN);
                }
            }
            if (children.item(i).getNodeName().equalsIgnoreCase("BidMultipliers")) {
                for (int j=0; j<children.item(i).getChildNodes().getLength(); j++) {
                    if (children.item(i).getChildNodes().item(j).getNodeName().equalsIgnoreCase("ManualCPC")) {
                        NodeList manualCPCNode = children.item(i).getChildNodes().item(j).getChildNodes();
                        ManualCPCAdGroupExperimentBidMultipliers manualCPC = new ManualCPCAdGroupExperimentBidMultipliers();
                        for (int k=0; k<manualCPCNode.getLength(); k++) {
                            if (manualCPCNode.item(k).getNodeName().equalsIgnoreCase("MaxCpcMultiplier")) {
                                manualCPC.setMaxCpcMultiplier(GetBidMultiplier(manualCPCNode.item(k).getChildNodes()));
                            }
                            if (manualCPCNode.item(k).getNodeName().equalsIgnoreCase("MaxContentCpcMultiplier")) {
                                manualCPC.setMaxContentCpcMultiplier(GetBidMultiplier(manualCPCNode.item(k).getChildNodes()));
                            }
                        }
                        adGroupExperimentData.setExperimentBidMultipliers(manualCPC);
                    }
                    if (children.item(i).getChildNodes().item(j).getNodeName().equalsIgnoreCase("ManualCPM")) {
                        NodeList manualCPMNode = children.item(i).getChildNodes().item(j).getChildNodes();
                        ManualCPMAdGroupExperimentBidMultipliers manualCPM = new ManualCPMAdGroupExperimentBidMultipliers();
                        for (int k=0; k<manualCPMNode.getLength(); k++) {
                            if (manualCPMNode.item(k).getNodeName().equalsIgnoreCase("MaxCpmMultiplier")) {
                                manualCPM.setMaxCpmMultiplier(GetBidMultiplier(manualCPMNode.item(k).getChildNodes()));
                            }
                        }
                        adGroupExperimentData.setExperimentBidMultipliers(manualCPM);
                    }
                }
            }
        }
        return adGroupExperimentData;
    }

    private BidMultiplier GetBidMultiplier(NodeList children) {
        BidMultiplier bidMultiplier = new BidMultiplier();
        for (int i = 0; i < children.getLength(); i++) {
            if (children.item(i).getNodeName().equalsIgnoreCase("multiplier")) {
                bidMultiplier.setMultiplier(Double.valueOf(children.item(i).getTextContent()));
            }
        }
        return bidMultiplier;
    }

    private Document loadXMLFromString(String xml) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        factory.setNamespaceAware(true); // never forget this!
        InputSource is = new InputSource(new StringReader(xml));
        return builder.parse(is);
    }

    protected ArrayList<AdGroupReport> GetAdGroupStats(String clientId) {

        ArrayList<AdGroupReport> result = new ArrayList<AdGroupReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get AdGroup Service
        try {
            AdGroupServiceInterface adGroupService = sf.GetAdGroupService(clientId);

            int offset = 0;
            Selector selector = new Selector();

            selector.setPaging(new Paging(offset, PAGE_SIZE));
            selector.setOrdering(new OrderBy[]{new OrderBy("Name", SortOrder.ASCENDING)});

            selector.setFields(new String[]{
                    "BiddingStrategyType",
                    "CampaignId",
                    // "ContentBid",
                    "CpcBid",
                    "CpmBid",
                    "Id",
                    "Name",
                    "Settings",
                    "Status",
                    "TargetCpaBid"
            });

            Predicate predicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[]{"REMOVED"});
            Predicate[] predicates = new Predicate[]{predicate};
            selector.setPredicates(predicates);

            AdGroupPage page = null;

            try {

                do {

                    page = adGroupService.get(selector);

                    if (page.getEntries() != null) {
                        for (AdGroup adGroup : page.getEntries()) {
                            AdGroupReport adGroupReport = new AdGroupReport();

                            if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                                adGroupReport.BiddingStrategyType = "BO";
                            } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                                adGroupReport.BiddingStrategyType = "CO";
                            } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                                adGroupReport.BiddingStrategyType = "MCPC";
                            } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                                adGroupReport.BiddingStrategyType = "MCPM";
                            }/* else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.PERCENT_CPA) {
                                adGroupReport.BiddingStrategyType = "PCPA";
                            }   */

                            adGroupReport.CampaignId = adGroup.getCampaignId();
                            adGroupReport.Id = adGroup.getId();
                            adGroupReport.Name = adGroup.getName();

                            if (adGroup.getStatus() == AdGroupStatus.ENABLED) {
                                adGroupReport.Status = "E";
                            } else if (adGroup.getStatus() == AdGroupStatus.REMOVED) {
                                adGroupReport.Status = "D";
                            } else if (adGroup.getStatus() == AdGroupStatus.PAUSED) {
                                adGroupReport.Status = "P";
                            }

                            for (Bids bid : adGroup.getBiddingStrategyConfiguration().getBids()) {
                                if (bid instanceof CpcBid) {
                                    if (((CpcBid) bid).getBid() != null) {
                                        adGroupReport.ContentBid = (double) ((CpcBid) bid).getBid().getMicroAmount() / (double) 1000000;
                                    }
                                    if (((CpcBid) bid).getBid() != null) {
                                        adGroupReport.CpcBid = (double) ((CpcBid) bid).getBid().getMicroAmount() / (double) 1000000;
                                    }
                                } else if (bid instanceof CpmBid) {
                                    if (((CpmBid) bid).getBid() != null) {
                                        adGroupReport.CpmBid = (double) ((CpmBid) bid).getBid().getMicroAmount() / (double) 1000000;
                                    }
                                }else if (bid instanceof CpaBid) {
                                    if (((CpaBid) bid).getBid() != null) {
                                        adGroupReport.TargetCpaBid = (double) ((CpaBid) bid).getBid().getMicroAmount() / (double) 1000000;
                                    }
                                }
                            }

                            if (adGroup.getSettings() != null) {
                                for (Setting setting : adGroup.getSettings()) {
                                    if (setting instanceof TargetingSetting) {
                                        TargetingSettingDetail[] details = ((TargetingSetting) setting).getDetails();
                                        if (details != null) {
                                            adGroupReport.Details = new GA_TargetingSettingDetail[details.length];
                                            for (int i = 0; i < details.length; i++) {
                                                adGroupReport.Details[i] = new GA_TargetingSettingDetail();

                                                if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.USER_INTEREST_AND_LIST) {
                                                    adGroupReport.Details[i].CriterionTypeGroup = "UI";
                                                } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.VERTICAL) {
                                                    adGroupReport.Details[i].CriterionTypeGroup = "V";
                                                } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.GENDER) {
                                                    adGroupReport.Details[i].CriterionTypeGroup = "G";
                                                } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.AGE_RANGE) {
                                                    adGroupReport.Details[i].CriterionTypeGroup = "A";
                                                } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.PLACEMENT) {
                                                    adGroupReport.Details[i].CriterionTypeGroup = "P";
                                                } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.UNKNOWN) {
                                                    adGroupReport.Details[i].CriterionTypeGroup = "UN";
                                                } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.KEYWORD) {
                                                    adGroupReport.Details[i].CriterionTypeGroup = "K";
                                                }

                                                adGroupReport.Details[i].TargetAll = details[i].getTargetAll();
                                            }
                                        }
                                    }
                                }
                            }


                            result.add(adGroupReport);

                        }
                    }


                    offset += PAGE_SIZE;
                    selector.getPaging().setStartIndex(offset);

                } while (offset < page.getTotalNumEntries());

            } catch (RemoteException ex) {
                ex.printStackTrace(System.out);
            }
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        }

        return result;

    }

    protected ArrayList<AdGroupReport> GetAdGroupStatsWithRemoved(String clientId, ArrayList<String> campaignsToFilterOut) {

        ArrayList<AdGroupReport> result = new ArrayList<AdGroupReport>();

        try {
            // Get the instance of service's factory
            ServiceFactory sf = ServiceFactory.getInstance();

            // Get AdGroup Service
            AdGroupServiceInterface adGroupService = sf.GetAdGroupService(clientId);

            int offset = 0;
            Selector selector = new Selector();

            selector.setPaging(new Paging(offset, PAGE_SIZE));
            selector.setOrdering(new OrderBy[]{new OrderBy("Name", SortOrder.ASCENDING)});

            selector.setFields(new String[]{
                    "BiddingStrategyType",
                    "CampaignId",
                    // "ContentBid",
                    "CpcBid",
                    "CpmBid",
                    "Id",
                    "Name",
                    "Settings",
                    "Status",
                    "TargetCpaBid"
            });

            if (!campaignsToFilterOut.isEmpty()) {
                Object[] campaignsToArray = campaignsToFilterOut.toArray();
                String[] campaigns = new String[campaignsToArray.length];
                for (int i=0; i<campaignsToArray.length; i++) {
                    campaigns[i] = (String)campaignsToArray[i];
                }
                Predicate predicate = new Predicate("CampaignId", PredicateOperator.NOT_IN, campaigns);
                Predicate[] predicates = new Predicate[]{predicate};
                selector.setPredicates(predicates);
            }

            AdGroupPage page = null;

            do {

                page = adGroupService.get(selector);

                if (page.getEntries() != null) {
                    for (AdGroup adGroup : page.getEntries()) {
                        AdGroupReport adGroupReport = new AdGroupReport();

                        if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                            adGroupReport.BiddingStrategyType = "BO";
                        } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                            adGroupReport.BiddingStrategyType = "CO";
                        } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                            adGroupReport.BiddingStrategyType = "MCPC";
                        } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                            adGroupReport.BiddingStrategyType = "MCPM";
                        }

                        adGroupReport.CampaignId = adGroup.getCampaignId();
                        adGroupReport.Id = adGroup.getId();
                        adGroupReport.Name = adGroup.getName();

                        if (adGroup.getStatus() == AdGroupStatus.ENABLED) {
                            adGroupReport.Status = "E";
                        } else if (adGroup.getStatus() == AdGroupStatus.REMOVED) {
                            adGroupReport.Status = "D";
                        } else if (adGroup.getStatus() == AdGroupStatus.PAUSED) {
                            adGroupReport.Status = "P";
                        }

                        for (Bids bid : adGroup.getBiddingStrategyConfiguration().getBids()) {
                            if (bid instanceof CpcBid) {
                                if (((CpcBid)bid).getBid() != null) {
                                    adGroupReport.ContentBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                }
                                if (((CpcBid)bid).getBid() != null) {
                                    adGroupReport.CpcBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                }
                            } else if (bid instanceof CpmBid) {
                                if (((CpmBid)bid).getBid() != null) {
                                    adGroupReport.CpmBid = (double)((CpmBid)bid).getBid().getMicroAmount() / (double)1000000;
                                }
                            }  else if (bid instanceof CpaBid) {
                                if (((CpaBid)bid).getBid() != null) {
                                    adGroupReport.TargetCpaBid = (double)((CpaBid)bid).getBid().getMicroAmount() / (double)1000000;
                                }
                            }
                        }

                        if (adGroup.getSettings() != null) {
                            for (Setting setting : adGroup.getSettings()) {
                                if (setting instanceof TargetingSetting) {
                                    TargetingSettingDetail[] details = ((TargetingSetting)setting).getDetails();
                                    if (details != null) {
                                        adGroupReport.Details = new GA_TargetingSettingDetail[details.length];
                                        for (int i=0; i<details.length; i++) {
                                            adGroupReport.Details[i] = new GA_TargetingSettingDetail();

                                            if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.USER_INTEREST_AND_LIST) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "UI";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.VERTICAL) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "V";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.GENDER) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "G";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.AGE_RANGE) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "A";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.PLACEMENT) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "P";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.UNKNOWN) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "UN";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.KEYWORD) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "K";
                                            }

                                            adGroupReport.Details[i].TargetAll = details[i].getTargetAll();
                                        }
                                    }
                                }
                            }
                        }


                        result.add(adGroupReport);

                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());

        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        }

        return result;

    }

}
